Deconstruction data preparation

Introduction and Project Goals

The 2018 Deconstruction Data Analysis uses project data from residential single family homes removed under a City of Portland Deconstruction permit. The goal of the data analysis is to quantify the net environmental benefits resulting from avoided disposal of materials due to salvage/reuse (measured as Global Warming Potential and Primary Energy Demand impacts).

Figure 1 illustrates the workflow process for the analysis.

####FIGURE 1: Project Workflow

####FIGURE 1: Project Workflow

This data preparation notebook uses the decon_material_weight.csv output from the 01_decon_material_weight_conversion.Rmd file and additional input data sources to prepare a data file with impacts associated with the line item of materials reported in the reciepts. Also included are some optional basic data structure exploration routines which may be of interest to analysts and stakeholders, but are not directly involved in the reporting of environmental impacts.

Notebook Setup

The analysis is intended to be reproducible using R coding procedures and employs the following R Packages:

package name
fBasics
ggthemes
grDevices
knitr
rebus
rstudioapi
scales
tidyverse

Prior to executing code and producing outputs, the packages must be installed and accessed, and basic features of the document set up by specifying code chunk defaults.

## Loading required package: fBasics
## Loading required package: timeDate
## Loading required package: timeSeries
## Loading required package: ggthemes
## Loading required package: knitr
## Loading required package: rebus
## Loading required package: rstudioapi
## Loading required package: scales
## 
## Attaching package: 'scales'
## The following object is masked from 'package:rebus':
## 
##     alpha
## Loading required package: tidyverse
## -- Attaching packages ----------------------------------------------------------------------------------------------------------------------- tidyverse 1.2.1 --
## v ggplot2 3.0.0     v purrr   0.2.5
## v tibble  1.4.2     v dplyr   0.7.6
## v tidyr   0.8.1     v stringr 1.3.1
## v readr   1.1.1     v forcats 0.3.0
## -- Conflicts -------------------------------------------------------------------------------------------------------------------------- tidyverse_conflicts() --
## x ggplot2::alpha()    masks scales::alpha(), rebus::alpha()
## x readr::col_factor() masks scales::col_factor()
## x purrr::discard()    masks scales::discard()
## x dplyr::filter()     masks timeSeries::filter(), stats::filter()
## x dplyr::lag()        masks timeSeries::lag(), stats::lag()
## x stringr::regex()    masks rebus::regex()
## [[1]]
## [1] TRUE
## 
## [[2]]
## [1] TRUE
## 
## [[3]]
## [1] TRUE
## 
## [[4]]
## [1] TRUE
## 
## [[5]]
## [1] TRUE
## 
## [[6]]
## [1] TRUE
## 
## [[7]]
## [1] TRUE
## 
## [[8]]
## [1] TRUE

Notebook Contents and Output

This notebook includes some optional basic data structure exploration, which is indicated using the include = argument inside the code chunk title string (curly braces after the code chunk opening ticks) Users can deselect any optional output in this notebook by changing the include = argument from TRUE to FALSE. Additional summary information may also be selected to print by removing the comment # character from in front of the summary call in the appropriate code chunks.

Data file output with descriptions are given in the following table. All output resides inside the R project folder:

TABLE 1: Data Preparation File Output Objects

Output Name Description
dropbox_EOL_weight_composition.csv EOL weight (kg) for assigned composition of dropbox/dropbox materials
decon_house_weights.csv project based material weights converted to ‘kg’ for impact calculations
deconMaterialName_SimpleEOLname_mapping.csv mapping of different material naming schemes used for data wrangling
deconData.csv deconstruction scenario impacts by project, material, and EOL disposition including dropbox
demoData.csv demolition scenario impacts by project, material, and EOL disposition including dropbox

Data Import

# from 01_decon_material_weight_conversion.Rmd
decon_material_weight <- read_csv("intermediary/decon_material_weight.csv")
## Warning: Missing column names filled in: 'X1' [1]
## Parsed with column specification:
## cols(
##   X1 = col_integer(),
##   project = col_integer(),
##   contractor = col_character(),
##   house_age = col_integer(),
##   house_size = col_integer(),
##   description = col_character(),
##   deconMaterialName = col_character(),
##   listed_quantity = col_double(),
##   listed_units = col_character(),
##   dimensions = col_character(),
##   dimensional_units = col_character(),
##   converted_quantity = col_double(),
##   converted_quantity_units = col_character()
## )
# remove index and reformat project and contractor factors to character vectors
decon_material_weight <- decon_material_weight[,-1]
decon_material_weight$project <- as.character(decon_material_weight$project)


# sourced from DEQ contact Palmeri.Jordan@deq.state.or.us
impact_data <- read_csv("data/LCA impact data for Decon Tool.csv")
## Warning: Missing column names filled in: 'X15' [15], 'X16' [16],
## 'X17' [17], 'X18' [18], 'X19' [19]
## Parsed with column specification:
## cols(
##   deconMaterialName = col_character(),
##   LCstage = col_character(),
##   disposition = col_character(),
##   impactValue = col_double(),
##   impactUnit = col_character(),
##   declaredUnit = col_character(),
##   impactCategory = col_character(),
##   impactMethdology = col_character(),
##   DatasetName = col_character(),
##   Geography = col_character(),
##   Year = col_character(),
##   Source = col_character(),
##   Custom = col_character(),
##   Comments = col_character(),
##   X15 = col_character(),
##   X16 = col_character(),
##   X17 = col_character(),
##   X18 = col_character(),
##   X19 = col_character()
## )
EOL <- read_csv("data/EOL.csv")
## Parsed with column specification:
## cols(
##   Activity = col_character(),
##   Stream = col_character(),
##   SimpleEOLname = col_character(),
##   deconMaterialName = col_character(),
##   Distribution = col_character(),
##   kg = col_character(),
##   `Percent Recycled` = col_double(),
##   `Percent Incinerated` = col_double(),
##   `Percent Landfilled` = col_double(),
##   `Percent Reuse` = col_integer()
## )
# for sensitivity analyses, replace this line with the appropriate alternative EOL file
# EOL <- read_csv("data/EOLalt.csv")

Projects/Houses

# create a new project characteristics data table, coerce project and contractor column types to character factors, and optionally print a summary
project_characteristics <- distinct(select(decon_material_weight, c("project", "house_age", "house_size")))
# summary(project_characteristics)

# calculate and save mean average of the house age and size statistics
average_house_age <- round(mean(project_characteristics$house_age))
average_house_size <- round(mean(project_characteristics$house_size))
number_of_houses <- round(length(project_characteristics$project))

There are 36 projects in the data set. The average house was 112 years old and roughly 1177 square feet.

# split the full set of decon_material_weight data into two data frames: anything that didn't go into a dropbox vs anything that did! 
salvage_materials_weight <- decon_material_weight %>% 
   filter(deconMaterialName != "dropbox") %>%
   mutate(US_lbs = converted_quantity * 2.2046)

dropbox_weight <- decon_material_weight %>% 
   filter(deconMaterialName == "dropbox") %>%
   select(c("project", "contractor", "house_age", "house_size", "deconMaterialName", "converted_quantity", "converted_quantity_units") ) %>%
   group_by(contractor, project) %>%
   summarise(total_dropbox_quantity = sum(converted_quantity)) %>%
   add_column(quantity_units = "kg")

rm(decon_material_weight)

The data is sum totaled by project to get a total weight of all salvaged materials and total weight of all dropbox tickets per project. These salvage and dropbox totaled weight values are added to get a combined total_house_weight which serves as an estimate the weight of the house without the foundation. This in turn is used to generate a percentage of house material salvaged by weight for each project.

# save project weight objects
reuse_by_project <- salvage_materials_weight %>%
   group_by(contractor, project) %>%
   summarise(total_salvage_quantity = sum(converted_quantity)) %>%
   add_column(quantity_units = "kg")

house_weight <- full_join(reuse_by_project, dropbox_weight, by = c("project", "contractor")) %>%
   mutate(total_house_weight = total_salvage_quantity + total_dropbox_quantity) %>%
   mutate(total_house_weight_units = "kg") %>%
   mutate(percent_salvaged = (total_salvage_quantity / total_house_weight * 100)) %>%
   rename(salvage_quantity_units = quantity_units.x) %>%
   rename(dropbox_quantity_units = quantity_units.y) %>%
   left_join(project_characteristics, by = "project") %>%
   arrange(desc(percent_salvaged)) %>%
   group_by(contractor)

# save output for later use 

write_csv(house_weight, "intermediary/house_weight.csv")

# clear the environment of unneeded objects
rm(reuse_by_project)

summary(select(house_weight, c("total_salvage_quantity", "total_dropbox_quantity", "total_house_weight", "percent_salvaged", "house_age", "house_size") ))
## Adding missing grouping variables: `contractor`
##   contractor        total_salvage_quantity total_dropbox_quantity
##  Length:36          Min.   :1308           Min.   : 4345         
##  Class :character   1st Qu.:3268           1st Qu.: 7294         
##  Mode  :character   Median :4443           Median :13934         
##                     Mean   :4802           Mean   :13052         
##                     3rd Qu.:5816           3rd Qu.:16738         
##                     Max.   :9448           Max.   :24830         
##  total_house_weight percent_salvaged   house_age     house_size  
##  Min.   : 8141      Min.   : 7       Min.   : 90   Min.   : 640  
##  1st Qu.:12492      1st Qu.:18       1st Qu.:107   1st Qu.: 897  
##  Median :18198      Median :28       Median :111   Median :1132  
##  Mean   :17854      Mean   :29       Mean   :112   Mean   :1177  
##  3rd Qu.:21404      3rd Qu.:37       3rd Qu.:118   3rd Qu.:1338  
##  Max.   :27892      Max.   :64       Max.   :137   Max.   :2341

The average house yielded 10586.6 pounds of materials for salvage and 28774.7 pounds of materials in dropboxes, which results in the (arithmetic mean) average of 29 percent material salvage by weight for this set of deconstruction projects.

Data visualization

A few initial data visualizations are explored in the following code chunks, most of which if included in a final report, will end up in an appendix.

The project team was interested in the relationship between the weight of salvaged and disposal materials and the size (square feet) of the house. The “Materials salvaged by house size” chart shows the scatterplot of these variables, with contractors indicated in the point colors. A positive relationship is expected here, and the plot confirms this by showing sparse instances in the upper left and lower right quadrants of the graph.

Impact Data

#impact_data <- impact_data %>%
#   select(c(1, 3:7))

# split impacts by disposition to create EOL scenario impact values
reuse_impacts <- impact_data %>%
   filter(.$disposition == "reuse")

demo_impacts <- impact_data %>%
   filter(.$disposition != "reuse")

Data Transformations for Analytical Use

Reuse & deconstruction salvage

Impacts on salvaged materials are calculated by joining the reuse_impacts to the salvage_materials_weight data and taking the product of the calculated_quantity and the impactValue, which is named material_impacts in the reuse_scenario data frame.

reuse_scenario <- salvage_materials_weight %>%
   inner_join(reuse_impacts, by = "deconMaterialName") %>%
   mutate(material_impacts = converted_quantity * impactValue) %>%
   mutate(material_impact_units = impactUnit) %>%
   select(c("project", "contractor", "house_age", "house_size", "deconMaterialName", "converted_quantity", "converted_quantity_units", "disposition", "impactCategory", "material_impacts", "material_impact_units")) %>%
   group_by(project, contractor, deconMaterialName, disposition, impactCategory)
 
    
reuse_scenario_impact_summary <- reuse_scenario %>%
   summarise(impact_sum = sum(material_impacts)) %>%
   left_join(project_characteristics, by = "project")  

Optional preliminary data visualizations of the salvaged materials are included.

Non-salvage (dropbox/dropbox) material impacts

In order to assign impacts to the dropbox materials, the following material distribution is applied to the total on each project.

# new deconMaterialName categories to incorporate later, leave commented out until update is released
# new_materials_demo_percentEOL <- EOL[76:86, c(3:4,7:9)]

# dropbox composition percentages to apply to dropbox total weight
dropbox_stream_distribution <- EOL[30:33, 3:5]
dropbox_stream_distribution$Distribution <- as.numeric(str_sub(dropbox_stream_distribution$Distribution, 1, -2))/100

# reshape table for extracting kg by EOL disposition
dropbox_EOL <- EOL[30:33, c(3:4,7:9)] %>%
   gather("Percent Recycled", "Percent Incinerated", "Percent Landfilled",  key = "disposition_assignment", value = "percentage") %>%
   add_column(disposition = case_when(
      .$disposition_assignment == "Percent Recycled" ~ "recyclingGeneric",
      .$disposition_assignment == "Percent Incinerated" ~ "incineration",
      .$disposition_assignment == "Percent Landfilled" ~ "landfill")
      )
# merge the stream composition table with the EOL disposition assignment
dropbox_stream_EOL <- inner_join(dropbox_stream_distribution, dropbox_EOL, by = c("SimpleEOLname", "deconMaterialName")) %>%
   filter(percentage > 0) %>%
   add_column(target_units = rep("kg", length(.$percentage)))

# clean up intermediate objects
rm(dropbox_EOL)
rm(dropbox_stream_distribution)

Once these material composition and end-of-life disposition assignments are imposed on the total project dropbox weight, the values essentially become theoretical values subject to changing assumptions or updates in the metro C&D waste composition data. Each project is assigned the 6 dropbox_stream_EOL EOL percentages and then weights calculated for each EOL disposition assignment. Finally the impacts associated with this dropbox EOL assignment profile are calculated and saved as a separate output file.

dropbox_composition <- full_join(dropbox_weight, dropbox_stream_EOL,  by = c("quantity_units" = "target_units")) %>%
   mutate(kg_composition = total_dropbox_quantity * Distribution) %>%
   mutate(dropbox_EOL_kg = kg_composition * percentage)

write.csv(dropbox_composition, "intermediary/dropbox_EOL_weight_composition.csv")
rm(dropbox_weight)

# assign impacts to the EOL disposition kg and clean up for merge with `reuse_scenario`
dropbox_impacts <- left_join(dropbox_composition, impact_data, by = c("deconMaterialName", "disposition")) %>%
   full_join(project_characteristics) %>%
   mutate(material_impacts = dropbox_EOL_kg * impactValue) %>%
   rename(material_impact_units = impactUnit) %>%
   rename(quantity = dropbox_EOL_kg) %>%
   select("house_age", "house_size", "project", "contractor", "deconMaterialName", "quantity", "quantity_units", "disposition", "impactCategory", "material_impacts", "material_impact_units", "SimpleEOLname")
## Joining, by = "project"
ggplot(dropbox_impacts, aes(x = impactCategory, y = material_impacts, fill = SimpleEOLname) ) +
   geom_bar(stat = "identity", position = "dodge") +
   labs(x = "dropbox material impacts", y = "impact total: MJ for Energy and kg CO2e for GWP", fill = "") +
   scale_y_continuous(labels = comma) +
   scale_fill_manual(values = DEQ_pal[8:11]) +
   theme_tufte() +
   theme(legend.position = "top", legend.direction = "horizontal") +
   ggtitle("Dropbox impacts by material")

Before developing the final deconstruction scenario data table, we’ll need to bring the material_category_mapping into the reuse_scenario data frame and combine the reuse_scenario data frame with the dropbox_impacts. This yields the decon data frame of material quantities and impacts by project and material type for all materials presented in the receipts summary.

material_category_mapping <- EOL[1:28,3:4]
write.csv(material_category_mapping, "intermediary/deconMaterialName_SimpleEOLname_mapping.csv")
decon <- left_join(reuse_scenario, material_category_mapping, by = "deconMaterialName") %>%
   rename(quantity = converted_quantity) %>%
   rename(quantity_units = converted_quantity_units) %>%
   bind_rows(dropbox_impacts) %>%
   rename(impact_category = impactCategory) 

write.csv(decon, "intermediary/deconData.csv")

Data wrangling and objects for transport calculations

project_material_weight_sum <- salvage_materials_weight %>%
   group_by(project, deconMaterialName) %>%
   summarise(total_salvage_quantity = sum(converted_quantity)) %>%
   add_column(quantity_units = "kg")

write.csv(project_material_weight_sum, "intermediary/project_material_weight_sum.csv")

Demolition equivalent on salvaged materials

In order to obtain net benefits, the deconstruction scenario must be compared to the approximately equivalent demolition scenario. For materials that were salvaged, we will need to reassign the reuse dispositions accordingly and re-calculate the energy and carbon impacts.

# assign NonSalvage material dispositions 
demoEOL <- EOL[38:66, c(3:4,7:9)] %>%
   gather(`Percent Recycled`, `Percent Incinerated`, `Percent Landfilled`,  key = "disposition_assignment", value = "percentage") %>%
   mutate(disposition = case_when(
      .$disposition_assignment == "Percent Recycled" ~ "recyclingGeneric",
      .$disposition_assignment == "Percent Incinerated" ~ "incineration",
      .$disposition_assignment == "Percent Landfilled" ~ "landfill"
   ))

demo_scenario <- salvage_materials_weight %>%
   left_join(demoEOL, by = "deconMaterialName") %>%
   inner_join(demo_impacts, by = c("deconMaterialName", "disposition")) %>%
   mutate(percent_EOL_quantity = converted_quantity * percentage) %>%
   mutate(material_impacts = percent_EOL_quantity * impactValue) %>%
   mutate(material_impact_units = impactUnit) %>%
   rename(quantity = percent_EOL_quantity) %>%
   rename(quantity_units = converted_quantity_units) %>%
   select("house_age", "house_size", "project", "contractor", "deconMaterialName", "quantity", "quantity_units", "disposition", "impactCategory", "material_impacts", "material_impact_units", "SimpleEOLname")

Cleaning up the demo_scenario data frame yields the demo data that can be used to differentiate net benefits from the decon data.

demo <- demo_scenario %>%
   bind_rows(dropbox_impacts) %>%
   rename(impact_category = impactCategory) %>%
   filter(quantity != 0)

write.csv(demo, "intermediary/demoData.csv")

Data Summary and Further Use

The two scenario data frames are saved as separate files and each contain the following variables: house_age, house_size, project, contractor, deconMaterialName, quantity, quantity_units, disposition, impact_category, material_impacts, material_impact_units, SimpleEOLname

To accurately represent net benefits of deconstruction over demolition, these figures must also account for transportation impacts. The data prepared in this notebook will be used in 03_Transport.Rmd to determine the material based transport impacts. Once the transport related impacts are calculated, the decon and demo data frames will be combined with the transport impacts in 04_decon_data_analysis2018 and the net benefits calculated within a final report.